home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint110s.zoo / procfs.c < prev    next >
C/C++ Source or Header  |  1994-02-15  |  18KB  |  744 lines

  1. /*
  2. Copyright 1991,1992 Eric R. Smith.
  3. Copyright 1992,1993,1994 Atari Corporation.
  4. All rights reserved.
  5.  */
  6.  
  7. /* PROC pseudo-filesystem routines */
  8. /* basically just to allow 'ls -l X:' to give a list of active processes
  9.  * some things to note:
  10.  * process names are given as name.XXX, where 'XXX' is the pid of the
  11.  *   process
  12.  * process attributes depend on the run queue as follows:
  13.  *   RUNNING:    0x00        (normal)
  14.  *   READY:    0x01        (read-only)
  15.  *   WAIT:    0x20        (archive bit)
  16.  *   IOBOUND:    0x21        (archive bit+read-only)
  17.  *   ZOMBIE:    0x22        (archive+hidden)
  18.  *   TSR:    0x02        (hidden)
  19.  *   STOP:    0x24        (archive bit+system)
  20.  * the general principle is: inactive processes have the archive bit (0x20)
  21.  * set, terminated processes have the hidden bit (0x02) set, stopped processes
  22.  * have the system bit (0x04) set, and the read-only bit is used to
  23.  * otherwise distinguish states (which is unfortunate, since it would be
  24.  * nice if this bit corresponded with file permissions).
  25.  */
  26.  
  27. #include "mint.h"
  28.  
  29.  
  30. static long    ARGS_ON_STACK proc_root    P_((int drv, fcookie *fc));
  31. static long    ARGS_ON_STACK proc_lookup    P_((fcookie *dir, const char *name, fcookie *fc));
  32. static long    ARGS_ON_STACK proc_getxattr    P_((fcookie *fc, XATTR *xattr));
  33. static long    ARGS_ON_STACK proc_chattr    P_((fcookie *fc, int attrib));
  34. static long    ARGS_ON_STACK proc_chown    P_((fcookie *fc, int uid, int gid));
  35. static long    ARGS_ON_STACK proc_chmode    P_((fcookie *fc, unsigned mode));
  36. static long    ARGS_ON_STACK proc_rmdir    P_((fcookie *dir, const char *name));
  37. static long    ARGS_ON_STACK proc_remove    P_((fcookie *dir, const char *name));
  38. static long    ARGS_ON_STACK proc_getname    P_((fcookie *root, fcookie *dir, char *pathname,
  39.                             int size));
  40. static long    ARGS_ON_STACK proc_rename    P_((fcookie *olddir, char *oldname,
  41.                     fcookie *newdir, const char *newname));
  42. static long    ARGS_ON_STACK proc_opendir    P_((DIR *dirh, int flags));
  43. static long    ARGS_ON_STACK proc_readdir    P_((DIR *dirh, char *nm, int nmlen, fcookie *));
  44. static long    ARGS_ON_STACK proc_rewinddir    P_((DIR *dirh));
  45. static long    ARGS_ON_STACK proc_closedir    P_((DIR *dirh));
  46. static long    ARGS_ON_STACK proc_pathconf    P_((fcookie *dir, int which));
  47. static long    ARGS_ON_STACK proc_dfree    P_((fcookie *dir, long *buf));
  48. static DEVDRV *    ARGS_ON_STACK proc_getdev    P_((fcookie *fc, long *devsp));
  49.  
  50. static long    ARGS_ON_STACK proc_open    P_((FILEPTR *f));
  51. static long    ARGS_ON_STACK proc_write    P_((FILEPTR *f, const char *buf, long bytes));
  52. static long    ARGS_ON_STACK proc_read    P_((FILEPTR *f, char *buf, long bytes));
  53. static long    ARGS_ON_STACK proc_lseek    P_((FILEPTR *f, long where, int whence));
  54. static long    ARGS_ON_STACK proc_ioctl    P_((FILEPTR *f, int mode, void *buf));
  55. static long    ARGS_ON_STACK proc_datime    P_((FILEPTR *f, short *time, int rwflag));
  56. static long    ARGS_ON_STACK proc_close    P_((FILEPTR *f, int pid));
  57.  
  58. /* dummy routines from biosfs.c */
  59. extern long    ARGS_ON_STACK null_select    P_((FILEPTR *f, long p, int mode));
  60. extern void    ARGS_ON_STACK null_unselect    P_((FILEPTR *f, long p, int mode));
  61.  
  62. static PROC *    name2proc    P_((const char *name));
  63.  
  64.  
  65. DEVDRV proc_device = {
  66.     proc_open, proc_write, proc_read, proc_lseek, proc_ioctl, proc_datime,
  67.     proc_close, null_select, null_unselect
  68. };
  69.  
  70. FILESYS proc_filesys = {
  71.     (FILESYS *)0,
  72.     0,
  73.     proc_root,
  74.     proc_lookup, nocreat, proc_getdev, proc_getxattr,
  75.     proc_chattr, proc_chown, proc_chmode,
  76.     nomkdir, proc_rmdir, proc_remove, proc_getname, proc_rename,
  77.     proc_opendir, proc_readdir, proc_rewinddir, proc_closedir,
  78.     proc_pathconf, proc_dfree,
  79.     nowritelabel, noreadlabel, nosymlink, noreadlink, nohardlink,
  80.     nofscntl, nodskchng
  81. };
  82.  
  83. long ARGS_ON_STACK 
  84. proc_root(drv, fc)
  85.     int drv;
  86.     fcookie *fc;
  87. {
  88.     if (drv == PROCDRV) {
  89.         fc->fs = &proc_filesys;
  90.         fc->dev = drv;
  91.         fc->index = 0L;
  92.         return 0;
  93.     }
  94.     fc->fs = 0;
  95.     return EINTRN;
  96. }
  97.  
  98. static PROC *
  99. name2proc(name)
  100.     const char *name;
  101. {
  102.     const char *pstr;
  103.     char c;
  104.     int i;
  105.  
  106.     pstr = name;
  107.     while ( (c = *name++) != 0) {
  108.         if (c == '.')
  109.             pstr = name;
  110.     }
  111.     if (!isdigit(*pstr) && *pstr != '-')
  112.         return 0;
  113.     i = (int)atol(pstr);
  114.     if (i == -1)
  115.         return curproc;
  116.     else if (i == -2)
  117.         i = curproc->ppid;
  118.     return pid2proc(i);
  119. }
  120.  
  121. static long ARGS_ON_STACK 
  122. proc_lookup(dir, name, fc)
  123.     fcookie *dir;
  124.     const char *name;
  125.     fcookie *fc;
  126. {
  127.     PROC *p;
  128.  
  129.     if (dir->index != 0) {
  130.         DEBUG(("proc_lookup: bad directory"));
  131.         return EPTHNF;
  132.     }
  133.  
  134. /* special case: an empty name in a directory means that directory */
  135. /* so does "." */
  136.     if (!*name || (name[0] == '.' && name[1] == 0)) {
  137.         *fc = *dir;
  138.         return 0;
  139.     }
  140.  
  141. /* another special case: ".." could be a mount point */
  142.     if (!strcmp(name, "..")) {
  143.         *fc = *dir;
  144.         return EMOUNT;
  145.     }
  146.  
  147.     if (0 == (p = name2proc(name))) {
  148.         DEBUG(("proc_lookup: name not found"));
  149.         return EFILNF;
  150.     } else {
  151.         fc->index = (long)p;
  152.         fc->fs = &proc_filesys;
  153.         fc->dev = PROC_RDEV_BASE | p->pid;
  154.     }
  155.     return 0;
  156. }
  157.  
  158. static int p_attr[NUM_QUEUES] = {    /* attributes corresponding to queues */
  159.     0,            /* "RUNNING" */
  160.     0x01,            /* "READY" */
  161.     0x20,            /* "WAITING" */
  162.     0x21,            /* "IOBOUND" */
  163.     0x22,            /* "ZOMBIE" */
  164.     0x02,            /* "TSR" */
  165.     0x24,            /* "STOPPED" */
  166.     0x21            /* "SELECT" (same as IOBOUND) */
  167. };
  168.  
  169. static long ARGS_ON_STACK 
  170. proc_getxattr(fc, xattr)
  171.     fcookie *fc;
  172.     XATTR *xattr;
  173. {
  174.     PROC *p;
  175.     extern int proctime, procdate;    /* see dosmem.c */
  176.  
  177.     xattr->blksize = 1;
  178.     if (fc->index == 0) {
  179.         /* the root directory */
  180.         xattr->index = 0;
  181.         xattr->dev = xattr->rdev = PROCDRV;
  182.         xattr->nlink = 1;
  183.         xattr->uid = xattr->gid = 0;
  184.         xattr->size = xattr->nblocks = 0;
  185.         xattr->mtime = xattr->atime = xattr->ctime = proctime;
  186.         xattr->mdate = xattr->adate = xattr->cdate = procdate;
  187.         xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
  188.         xattr->attr = FA_DIR;
  189.         return 0;
  190.     }
  191.  
  192.     p = (PROC *)fc->index;
  193.     xattr->index = p->pid;
  194.     xattr->dev = xattr->rdev = PROC_RDEV_BASE | p->pid;
  195.     xattr->nlink = 1;
  196.     xattr->uid = p->ruid; xattr->gid = p->rgid;
  197.     xattr->size = xattr->nblocks = memused(p);
  198.     xattr->mtime = xattr->ctime = xattr->atime = p->starttime;
  199.     xattr->mdate = xattr->cdate = xattr->adate = p->startdate;
  200.     xattr->mode = S_IMEM | S_IRUSR | S_IWUSR;
  201.     xattr->attr = p_attr[p->wait_q];
  202.     return 0;
  203. }
  204.  
  205. static long ARGS_ON_STACK 
  206. proc_chattr(fc, attrib)
  207.     fcookie *fc;
  208.     int attrib;
  209. {
  210.     UNUSED(fc); UNUSED(attrib);
  211.  
  212.     return EACCDN;
  213. }
  214.  
  215. static long ARGS_ON_STACK 
  216. proc_chown(fc, uid, gid)
  217.     fcookie *fc;
  218.     int uid, gid;
  219. {
  220.     UNUSED(fc); UNUSED(uid); UNUSED(gid);
  221.     return EINVFN;
  222. }
  223.  
  224. static long ARGS_ON_STACK 
  225. proc_chmode(fc, mode)
  226.     fcookie *fc;
  227.     unsigned mode;
  228. {
  229.     UNUSED(fc); UNUSED(mode);
  230.     return EINVFN;
  231. }
  232.  
  233. static long ARGS_ON_STACK 
  234. proc_rmdir(dir, name)
  235.     fcookie *dir;
  236.     const char *name;
  237. {
  238.     UNUSED(dir); UNUSED(name);
  239.     return EPTHNF;
  240. }
  241.  
  242. static long ARGS_ON_STACK 
  243. proc_remove(dir, name)
  244.     fcookie *dir;
  245.     const char *name;
  246. {
  247.     PROC *p;
  248.  
  249.     if (dir->index != 0)
  250.         return EPTHNF;
  251.     p = name2proc(name);
  252.     if (!p)
  253.         return EFILNF;
  254.  
  255. /* this check is necessary because the Fdelete code checks for
  256.  * write permission on the directory, not on individual
  257.  * files
  258.  */
  259.     if (curproc->euid && curproc->ruid != p->ruid) {
  260.         DEBUG(("proc_remove: wrong user"));
  261.         return EACCDN;
  262.     }
  263.     post_sig(p, SIGTERM);
  264.     check_sigs();        /* it might have been us */
  265.     return 0;
  266. }
  267.  
  268. static long ARGS_ON_STACK 
  269. proc_getname(root, dir, pathname, size)
  270.     fcookie *root, *dir; char *pathname;
  271.     int size;
  272. {
  273.     PROC *p;
  274.  
  275.     UNUSED(root);
  276. /* BUG: we ought to look at size */
  277.     UNUSED(size);
  278.  
  279.     if (dir->index == 0)
  280.         *pathname = 0;
  281.     else {
  282.         p = (PROC *)dir->index;
  283.         ksprintf(pathname, "%s.03d", p->name, p->pid);
  284.     }
  285.     return 0;
  286. }
  287.  
  288. static long ARGS_ON_STACK 
  289. proc_rename(olddir, oldname, newdir, newname)
  290.     fcookie *olddir;
  291.     char *oldname;
  292.     fcookie *newdir;
  293.     const char *newname;
  294. {
  295.     PROC *p;
  296.     int i;
  297.  
  298.     if (olddir->index != 0 || newdir->index != 0)
  299.         return EPTHNF;
  300.     if ((p = name2proc(oldname)) == 0)
  301.         return EFILNF;
  302.  
  303.     oldname = p->name;
  304.     for (i = 0; i < PNAMSIZ; i++) {
  305.         if (*newname == 0 || *newname == '.') {
  306.             *oldname = 0; break;
  307.         }
  308.         *oldname++ = *newname++;
  309.     }
  310.     retu